package com.service.code;

import com.domain.HttpResponse;
import com.domain.ex.BizException;
import com.domain.ex.Codes;
import com.domain.myenum.CashCodeEnum;
import com.domain.page.Paginator;
import com.handler.email.Email;
import com.handler.email.EmailHandler;
import com.mapper.generator.ShCashHistoryMapper;
import com.mapper.self.CashHistoryMapper;
import com.mapper.self.IncomeWaterMapper;
import com.mapper.self.ShopMapper;
import com.pojo.ShCashHistory;
import com.pojo.ShShop;
import com.service.user.UserService;
import com.utils.DateUtils;
import com.utils.RandomUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * Created by Huoyunren on 2016/5/5.
 */
@Service
public class CashHistoryServiceImpl implements CashHistoryService {
  @Autowired
  private CashHistoryMapper cashHistoryMapper;
  @Autowired
  private ShCashHistoryMapper shCashHistoryMapper;
  @Autowired
  private UserService userService;
  @Autowired
  private IncomeWaterMapper incomeWaterMapper;
  @Autowired
  private ShopMapper shopMapper;
  @Autowired
  private EmailHandler emailHandler;

  @Override
  public Object sendCashCode(String buyerEmail, String shopEmail, BigDecimal cashAmount) {
    ensureIncomeCanBeCashed(buyerEmail, shopEmail, cashAmount);
    addCashHistory(buyerEmail, shopEmail, cashAmount);
    return HttpResponse.OK();
  }

  private void addCashHistory(String buyerEmail, String shopEmail, BigDecimal cashAmount) {
    ShCashHistory history = null;
    history = cashHistoryMapper.queryCashCode(buyerEmail);
    if (history == null) {
      history = new ShCashHistory();
      history.setEmail(buyerEmail);
      history.setCashAmount(cashAmount);
      history.setCashCode(RandomUtils.random6());
      history.setCreateTime(new Date());
      history.setCodeStatus(CashCodeEnum.UnUsed.getCode());
      shCashHistoryMapper.insertSelective(history);
    }
    cashMailNotify(buyerEmail, shopEmail, history.getCashCode(), history.getCashAmount(), null);
  }

  private void cashMailNotify(String buyerEmail, String shopEmail, String cashCode, BigDecimal cashAmount, String result) {
    ShShop shop = shopMapper.queryByEmail(shopEmail);
    Email email = new Email();
    String[] to = new String[1];
    to[0] = buyerEmail;
    email.setTo(to);
    StringBuffer buffer = new StringBuffer();
    buffer.append("提现码：" + cashCode);
    buffer.append("\n");
    buffer.append("提现金额：" + cashAmount);
    buffer.append("\n");
    buffer.append("提现时间：" + DateUtils.currentTime());
    buffer.append("\n");
    buffer.append("门店：" + shop.getName());
    email.setSubject("提现码");
    if (StringUtils.isNotBlank(result)) {
      email.setSubject("提现操作");
      buffer.append("\n");
      buffer.append("操作说明：" + result);
    }
    buffer.append("\n");
    buffer.append("官方网址：www.liuyuanwai.cn(备案审核中,敬请期待)");
    email.setContent(buffer.toString());
    email.setEnableHtml(Boolean.FALSE);
    emailHandler.asyncSendMail(email);
  }

  public void ensureIncomeCanBeCashed(String buyerEmail, String shopEmail, BigDecimal cashAmount) {
    if (cashAmount.compareTo(BigDecimal.ZERO) == 0) {
      throw BizException.create(Codes.SystemDeclare, "提现金额为零,无法提现");
    }
    BigDecimal income = userService.incomeSingleStatistic(buyerEmail, shopEmail);
    if (income == null) {
      throw BizException.create(Codes.SystemDeclare, "没有查询到收益记录");
    }
    if (cashAmount.compareTo(income) != 0) {
      throw BizException.create(Codes.SystemDeclare, "提现金额与用户收益不符,无法提现");
    }
  }

  @Override
  public Object cashAmount(String buyerEmail, String shopEmail, BigDecimal cashAmount, Integer cashCode) {
    if (cashCode == null) {
      return HttpResponse.create(Codes.SystemDeclare, "输入提现码");
    }
    ensureCashCodeLegal(buyerEmail, cashCode);
    ensureIncomeCanBeCashed(buyerEmail, shopEmail, cashAmount);
    cashHistoryMapper.updateCodeStatus(CashCodeEnum.Used.getCode(), buyerEmail, cashCode);
    incomeWaterMapper.updateIncomeStatus(buyerEmail, shopEmail);
    // - 邮件通知
    cashMailNotify(buyerEmail, shopEmail, String.valueOf(cashCode), cashAmount, "提现成功");
    return HttpResponse.OK();
  }

  public void ensureCashCodeLegal(String email, Integer cashCode) {
    ShCashHistory cashHistory = cashHistoryMapper.queryCashHistory(email, cashCode);
    if (cashHistory == null) {
      throw BizException.create(Codes.SystemDeclare, "提现码无效");
    }
    if (cashHistory.getCodeStatus() == CashCodeEnum.TimeOut.getCode()) {
      throw BizException.create(Codes.SystemDeclare, "提现码已过期,请重新申请");
    }
    if (cashHistory.getCodeStatus() == CashCodeEnum.Used.getCode()) {
      throw BizException.create(Codes.SystemDeclare, "提现码已被使用,请重新申请");
    }
  }

  @Override
  public Object list(Integer pageNo, Integer pageSize, String email) {
    if (pageNo > 0) {
      pageNo -= 1;
    }
    List<ShCashHistory> list = cashHistoryMapper.list(pageNo * pageSize, pageSize, email);
    return Paginator.instance(cashHistoryMapper.count(email), list);
  }
}
